package com.order.manager.Config;

import com.alibaba.fastjson2.JSONObject;
import com.order.manager.Model.other.RestBean;
import com.order.manager.filter.JwtFilter;
import com.order.manager.service.AuthUserDetailService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;

/**
 * Spring Security 配置类
 * 用于配置认证、授权规则和安全策略
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Resource
    AuthUserDetailService authUserDetailService; // 用户详情服务，用于加载用户信息
    @Resource
    JwtFilter jwtFilter; // JWT过滤器，用于验证令牌和设置安全上下文

    /**
     * 配置安全过滤链
     * @param http HttpSecurity构建器，用于配置安全规则
     * @return 配置好的SecurityFilterChain
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                /**
                 * 配置各接口的访问权限
                 * 格式：.requestMatchers(接口路径).权限控制规则
                 */
                .requestMatchers("/api/team/**").permitAll()
                .requestMatchers("/api/teamuser/**").permitAll()
                .requestMatchers("/api/teamitem/**").permitAll()
                //添加咖啡路径
                .requestMatchers("/api/coffee/**").permitAll()

                .requestMatchers("/api/auth/qrcode/**").permitAll()//验证码接口，允许所有访问
                .requestMatchers("/img/**").permitAll()//图片资源接口，允许所有访问
                .requestMatchers("/api/auth/login").permitAll()//用户登录接口，允许所有访问
                .requestMatchers("/api/auth/student/count").permitAll()//获取学生用户数量接口，允许所有访问
                .requestMatchers("/api/auth/order/count").permitAll()//获取订单数量接口，允许所有访问
                .requestMatchers("/api/auth/sender/count").permitAll()//获取配送员数量接口，允许所有访问
                .requestMatchers("/api/auth/register").permitAll()//用户注册接口，允许所有访问
                .requestMatchers("/api/upload/img/**").permitAll()//图片上传接口，允许所有访问
                .requestMatchers("/api/upload/img/img-d/**").permitAll()//图片上传接口，允许所有访问
                .requestMatchers("/api/order/apply/**").hasAnyAuthority("student","student_sender")//用户支付接口，需要student或student_sender权限
                .requestMatchers("/api/order/create").hasAnyAuthority("student","student_sender")//用户创建订单接口，需要student或student_sender权限
                .requestMatchers("/api/order/orderForShop/**").hasAnyAuthority("shop")//商店查询本商店订单接口，需要shop权限
                .requestMatchers("/api/order/query").hasAnyAuthority("student","student_sender")//用户查询自己订单接口，需要student或student_sender权限
                .requestMatchers("/api/order/refund/**").hasAnyAuthority("student","student_sender")//用户退款接口，需要student或student_sender权限
                .requestMatchers("/api/order/view/**").hasAnyAuthority("student","student_sender","shop")//用户查看订单信息接口，需要student、student_sender或shop权限
                .requestMatchers("/api/shop/get/**").hasAnyAuthority("student","student_sender","shop","school")//查看店铺信息接口，需要多种权限
                .requestMatchers("/api/shop/info").hasAnyAuthority("shop")//查看本店铺信息接口，需要shop权限
                .requestMatchers("/api/shop/insert").permitAll()//开设店铺接口，允许所有访问
                .requestMatchers("/api/shop/query/school/**").hasAnyAuthority("school")//学校查看所有商店信息接口，需要school权限
                .requestMatchers("/api/shop/select/collect/**").hasAnyAuthority("student","student_sender")//用户查看自己收藏店铺接口，需要student或student_sender权限
                .requestMatchers("/api/shop/select/**").hasAnyAuthority("student","student_sender")//用户查看审核通过店铺接口，需要student或student_sender权限
                .requestMatchers("/api/shop/show").hasAnyAuthority("shop")//店铺图标信息接口，需要shop权限
                .requestMatchers("/api/shop/size").permitAll()//返回审核通过店铺数量接口，允许所有访问
                .requestMatchers("/api/shop/update").hasAnyAuthority("shop")//店铺更新自己信息接口，需要shop权限
                .requestMatchers("/api/shop/update/state").hasAnyAuthority("shop","school")//店铺审核状态更新接口，需要shop或school权限
                .requestMatchers("/api/feedback/create").hasAnyAuthority("student","student_sender")//反馈信息创建接口，需要student或student_sender权限
                .requestMatchers("/api/feedback/freeback/**").hasAnyAuthority("school")//回复反馈信息接口，需要school权限
                .requestMatchers("/api/evaluate/create").hasAnyAuthority("student","student_sender")//评价信息创建接口，需要student或student_sender权限
                .requestMatchers("/api/evaluate/select/shopId/**").hasAnyAuthority("shop","student","student_sender")//查看商店评价接口，需要多种权限
                .requestMatchers("/api/evaluate/select/**").hasAnyAuthority("student","student_sender","shop")//查看订单评价接口，需要多种权限
                .requestMatchers("/api/auth/add/money").hasAnyAuthority("student","student_sender")//充值接口，需要student或student_sender权限
                .requestMatchers("/api/menu/del/**").hasAnyAuthority("shop")//删除菜品接口，需要shop权限
                .requestMatchers("/api/menu/get/**").hasAnyAuthority("student","student_sender")//获取菜品接口，需要student或student_sender权限
                .requestMatchers("/api/menu/insert").hasAnyAuthority("shop")//添加菜品接口，需要shop权限
                .requestMatchers("/api/menu/select/**").hasAnyAuthority("student","student_sender")//获取某商店菜品接口，需要student或student_sender权限
                .requestMatchers("/api/menu/shopSelect/**").hasAnyAuthority("shop")//商店获取本商店菜品接口，需要shop权限
                .requestMatchers("/api/menu/update").hasAnyAuthority("shop")//更新菜品信息接口，需要shop权限
                .requestMatchers("/api/sender/apply").hasAnyAuthority("student","student_sender","school")//配送员申请接口，需要多种权限
                .requestMatchers("/api/sender/audit").hasAnyAuthority("school")//配送员资格审核接口，需要school权限
                .requestMatchers("/api/sender/get/order/**").hasAnyAuthority("student_sender")//配送员接单接口，需要student_sender权限
                .requestMatchers("/api/sender/online/count").permitAll()//在线配送员数量接口，允许所有访问
                .requestMatchers("/api/sender/order/mySelf/**").hasAnyAuthority("student_sender")//配送员查看自己接单信息接口，需要student_sender权限
                .requestMatchers("/api/sender/query/school/**").hasAuthority("school")//学校查看配送员信息接口，需要school权限
                .requestMatchers("/api/sender/sender/state/**").hasAnyAuthority("school","student_sender")//配送员状态接口，需要多种权限
                .requestMatchers("/api/sender/senderInfo").hasAuthority("student_sender")//配送员信息接口，需要student_sender权限
                .requestMatchers("/api/complaint/select/**").permitAll()//反馈信息接口，允许所有访问
                .requestMatchers("/api/userAddress/del/**").hasAnyAuthority("student","student_sender")//删除用户地址接口，需要student或student_sender权限
                .requestMatchers("/api/userAddress/insert").hasAnyAuthority("student","student_sender")//增加用户地址接口，需要student或student_sender权限
                .requestMatchers("/api/userAddress/select").hasAnyAuthority("student","student_sender","shop")//查询用户地址接口，需要多种权限
                .requestMatchers("/api/userAddress/select/option").hasAnyAuthority("student","student_sender","shop")//用户获取地址列表接口，需要多种权限
                .requestMatchers("/api/examineShop/apply").hasAnyAuthority("shop")//商店审核接口，需要shop权限
                .requestMatchers("/api/examineShop/get/**").hasAnyAuthority("school")//获取审核信息接口，需要school权限
                .requestMatchers("/api/examineSender/examine/**").hasAuthority("school")//获取配送员审核信息接口，需要school权限
                .requestMatchers("/api/orderSender/find/list/**").hasAnyAuthority("student","student_sender")//配送员可配送订单接口，需要student或student_sender权限
                .requestMatchers("/api/collect/cancel/follow/**").hasAnyAuthority("student","student_sender")//取消收藏店铺接口，需要student或student_sender权限
                .requestMatchers("/api/collect/choose/**").hasAnyAuthority("student","student_sender")//用户检查收藏状态接口，需要student或student_sender权限
                .requestMatchers("/api/collect/follow/**").hasAnyAuthority("student","student_sender")//关注店铺接口，需要student或student_sender权限
                .requestMatchers("/api/online/**").permitAll()//在线相关接口，允许所有访问
                .anyRequest().authenticated());//其他所有请求都需要经过认证

        http.cors(cors -> cors.disable());//禁用CORS跨域支持
        http.csrf(csrf -> csrf.disable());//禁用CSRF防护，因为使用JWT无需CSRF

        http.logout(AbstractHttpConfigurer::disable);//取消默认登出页面的使用
        http.authenticationProvider(authenticationProvider());//设置自定义的认证提供器

        http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));//设置为无状态会话，使用JWT无需session
        http.httpBasic(AbstractHttpConfigurer::disable);//禁用httpBasic认证

        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);//将JWT过滤器添加到认证过滤器之前

        http.exceptionHandling(except -> except.authenticationEntryPoint(this::ex));//设置认证异常处理

        return http.build();//构建并返回SecurityFilterChain
    }

    /**
     * 配置认证提供器
     * @return 配置好的认证提供器
     */
    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();//创建DAO认证提供器
        provider.setPasswordEncoder(passwordEncoder());//设置密码编码器
        provider.setUserDetailsService(authUserDetailService);//设置用户详情服务
        return provider;//返回认证提供器
    }

    /**
     * 配置认证管理器
     * @param configuration 认证配置
     * @return 认证管理器
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();//从配置中获取认证管理器
    }

    /**
     * 配置密码编码器
     * @return BCrypt密码编码器
     */
    @Bean//声明为Bean，PasswordEncoder的实现类为BCryptPasswordEncoder
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();//返回BCrypt密码编码器实例
    }

    /**
     * 认证失败处理方法（未使用）
     */
    private void failureHandler(HttpServletRequest request, HttpServletResponse response,
                                AuthenticationException e) throws IOException {
        response.setCharacterEncoding("utf-8");//设置响应编码
        response.getWriter().write(JSONObject.toJSONString(RestBean.failure(401, e.getMessage())));//返回认证失败的JSON响应
    }

    /**
     * 认证异常处理方法
     */
    private void ex(HttpServletRequest request, HttpServletResponse response,
                    AuthenticationException e) throws IOException {
        response.setCharacterEncoding("utf-8");//设置响应编码
        response.getWriter().write(JSONObject.toJSONString(RestBean.failure(403, e.getMessage())));//返回权限拒绝的JSON响应
    }

/**
 * 1. JwtFilter 过滤器
 * 作用：拦截所有请求，验证请求头中的 JWT 令牌，并将认证信息存入安全上下文。
 * 关键逻辑：
 * 从请求头获取 token，验证令牌有效性（通过 jwtUtil.checkToken）。
 * 解析令牌获取用户 UUID，查询用户信息并生成认证令牌。
 * 使用 SecurityContextHolder 设置当前用户认证状态。
 * 2. SecurityConfig 配置类
 * 核心功能：配置安全策略，包括接口权限控制、认证提供者、会话管理等。
 * 关键配置：
 * 接口权限控制：通过 authorizeHttpRequests 定义各接口的访问权限（如 permitAll 或指定角色）。
 * 无状态会话：sessionCreationPolicy(STATELESS) 禁用 Session，完全依赖 JWT 令牌。
 * 过滤器链：将 JwtFilter 添加到 UsernamePasswordAuthenticationFilter 之前，确保令牌先验证。
 * 3. 认证与授权流程
 * 认证流程：
 * 用户登录时，服务器生成 JWT 令牌（包含用户 UUID、角色等信息）。
 * 客户端后续请求携带令牌，JwtFilter 验证令牌并设置用户认证状态。
 * 授权流程：
 * Spring Security 根据 @EnableWebSecurity 配置的规则，检查用户角色是否有权限访问接口。
 * 如接口 api/order/create 要求 student 或 student_sender 角色，无权限则返回 403 错误。
 */
}